package com.liu.controller;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.Order;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 1.PriorityOrdered接口 优先
 * 2.根据order值从小到大排序
 *      order值的获取方式有3种，并且有优先级顺序，Ordered接口（@PriorityOrdered是继承Ordered接口的）> @Order注解 > @Priority
 *      程序只会获取优先级最高的order值。比如既实现了Ordered接口又实现了@Order注解，程序只会取Ordered接口的order值。如果都没有实现
 * 3.如果都没有实现，就返回Integer.MAX_VALUE
 */
public class TestProcessOrder {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        //注册处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        List<BeanPostProcessor> list = new ArrayList(Arrays.asList( new P6(),new P1(), new P2(), new P3(), new P4(), new P5()));
        //通过AnnotationAwareOrderComparator比较
        list.sort(beanFactory.getDependencyComparator());

        list.forEach(processor->{
            //对bean执行处理器
            processor.postProcessBeforeInitialization(new Object(), "");
        });

    }

    @Order(1)
    static
    class P1 implements BeanPostProcessor {

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(this.getClass() + "  @Order(1)");
            return bean;
        }
    }

    @Order(2)
    static class P2 implements BeanPostProcessor {

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(this.getClass() + "  @Order(2)");
            return bean;
        }

    }

    static class P3 implements BeanPostProcessor, PriorityOrdered {

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(this.getClass() + "  PriorityOrdered");
            return bean;
        }

        @Override
        public int getOrder() {
            return 100;
        }
    }

    @Order(10)
    static class P4 implements BeanPostProcessor, Ordered {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(this.getClass() + "@Order(1)  implement Ordered 0  优先实现");
            return bean;
        }

        @Override
        public int getOrder() {
            return 0;
        }
    }

    static class P5 implements BeanPostProcessor {

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(this.getClass());
            return bean;
        }
    }
    static class P6 implements BeanPostProcessor {

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(this.getClass());
            return bean;
        }
    }
}
